require File.dirname(__FILE__)+"/../../test_helper"
require "starframe/sprite"
require "starframe/sprite/collision"
require "starframe/sprite/collidable"

class StarFrame::Sprite::Collision
  attr_accessor :target, :method_name, :options
  class Builder
    attr_accessor :target, :name, :method_name, :collision, :options
  end
end

class TestStarFrameSpriteCollidable < Test::Unit::TestCase
  class TestCollision < StarFrame::Sprite::Collision
    attr_accessor :options
    
    def collide? other
      (@target.position == other.target.position)
    end
  end
  class CollisionSprite < StarFrame::Sprite
    include StarFrame::Sprite::Collidable
    @texture = StarRuby::Texture.load "texture"
    
    attr_reader :other
    collision :test, TestCollision, :options do |other|
      @other = other
    end
  end
  
  def test_class_variables
    assert_kind_of     Hash,                                  CollisionSprite.collisions
    assert_equal       1,                                     CollisionSprite.collisions.size
    assert_instance_of StarFrame::Sprite::Collision::Builder, CollisionSprite.collisions[:test]
    assert_equal       TestCollision,                         CollisionSprite.collisions[:test].collision
    assert_equal       [:options],                            CollisionSprite.collisions[:test].options
    assert_equal       CollisionSprite,                       CollisionSprite.collisions[:test].target
  end
  
  def test_initialize
    sprite1 = CollisionSprite.new(10, 10)
    assert_kind_of     Hash,          sprite1.collisions
    assert_equal       1,             sprite1.collisions.size
    assert_instance_of TestCollision, sprite1.collisions[:test]
    assert_equal       [:options],    sprite1.collisions[:test].options
    assert_equal       sprite1,       sprite1.collisions[:test].target
    
    assert_respond_to sprite1, :_starframe_sprite_collision__collision_test
  end
  
  def test_collision_reader
    sprite = CollisionSprite.new(10, 10)
    assert_equal sprite.collisions[:animation1], sprite.collision(:animation1)
    assert_equal sprite.collisions[:animation2], sprite.collision(:animation2)
  end
  
  def test_is_collide?
    sprite1 = CollisionSprite.new(10, 10)
    sprite2 = CollisionSprite.new(10, 10)
    assert_equal true, sprite1.collide?(sprite2, :test, :test)
    assert_nil sprite1.other
    assert_nil sprite2.other
    
    sprite1 = CollisionSprite.new(10, 10)
    sprite2 = CollisionSprite.new(11, 10)
    assert_equal false, sprite1.collide?(sprite2, :test, :test)
    assert_nil sprite1.other
    assert_nil sprite2.other
  end
  
  def test_is_collide
    sprite1 = CollisionSprite.new(10, 10)
    sprite2 = CollisionSprite.new(10, 10)
    assert_equal true, sprite1.collide(sprite2, :test, :test)
    assert_equal sprite2, sprite1.other
    assert_equal sprite1, sprite2.other
    
    sprite1 = CollisionSprite.new(10, 10)
    sprite2 = CollisionSprite.new(11, 10)
    assert_equal false, sprite1.collide(sprite2, :test, :test)
    assert_nil sprite1.other
    assert_nil sprite2.other
  end
  
  def test_is_collide_q_long
    sprite1 = CollisionSprite.new(10, 10)
    sprite2 = CollisionSprite.new(10, 10)
    assert_equal true, sprite1.collision(:test).collide?(sprite2.collision(:test))
    assert_nil sprite1.other
    assert_nil sprite2.other
    
    sprite1 = CollisionSprite.new(10, 10)
    sprite2 = CollisionSprite.new(10, 11)
    assert_equal false, sprite1.collision(:test).collide?(sprite2.collision(:test))
    assert_nil sprite1.other
    assert_nil sprite2.other
  end
  
  def test_is_collide_long
    sprite1 = CollisionSprite.new(10, 10)
    sprite2 = CollisionSprite.new(10, 10)
    assert_equal true, sprite1.collision(:test).collide(sprite2.collision(:test))
    assert_equal sprite2, sprite1.other
    assert_equal sprite1, sprite2.other
    
    sprite1 = CollisionSprite.new(10, 10)
    sprite2 = CollisionSprite.new(10, 11)
    assert_equal false, sprite1.collision(:test).collide(sprite2.collision(:test))
    assert_nil sprite1.other
    assert_nil sprite2.other
  end
end
